package models

import (
	"errors"
	"fmt"
	"math"
	"time"
)

// MemberDiscountEngine 会员折扣引擎
type MemberDiscountEngine struct {
	LevelRules map[int]*MemberLevelRule
}

// MemberLevelRule 会员等级规则
type MemberLevelRule struct {
	Level            int             `json:"level"`
	Name             string          `json:"name"`
	MinPoints        int             `json:"min_points"`
	MaxPoints        int             `json:"max_points"`
	DiscountRate     float64         `json:"discount_rate"`
	Benefits         []MemberBenefit `json:"benefits"`
	UpgradeThreshold int             `json:"upgrade_threshold"`
	ValidityDays     int             `json:"validity_days"`
	SpecialRights    []SpecialRight  `json:"special_rights"`
}

// MemberBenefit 会员权益
type MemberBenefit struct {
	Type        string      `json:"type"`
	Name        string      `json:"name"`
	Description string      `json:"description"`
	Value       float64     `json:"value"`
	Limit       int         `json:"limit"`
	Frequency   string      `json:"frequency"` // daily, weekly, monthly, yearly
	ExpiryDate  int64       `json:"expiry_date"`
	Parameters  interface{} `json:"parameters"`
}

// SpecialRight 特殊权益
type SpecialRight struct {
	Type        string `json:"type"`
	Name        string `json:"name"`
	Description string `json:"description"`
	Enabled     bool   `json:"enabled"`
}

// MemberDiscountRequest 会员折扣计算请求
type MemberDiscountRequest struct {
	MemberID      int64   `json:"member_id"`
	MemberLevel   int     `json:"member_level"`
	OriginalPrice float64 `json:"original_price"`
	BookingType   string  `json:"booking_type"`
	BookingDate   string  `json:"booking_date"`
	VenueType     string  `json:"venue_type"`
	Duration      int     `json:"duration"`
}

// MemberDiscountResponse 会员折扣计算响应
type MemberDiscountResponse struct {
	MemberLevel       int                `json:"member_level"`
	LevelName         string             `json:"level_name"`
	OriginalPrice     float64            `json:"original_price"`
	DiscountAmount    float64            `json:"discount_amount"`
	FinalPrice        float64            `json:"final_price"`
	DiscountRate      float64            `json:"discount_rate"`
	AppliedBenefits   []AppliedBenefit   `json:"applied_benefits"`
	AvailableBenefits []AvailableBenefit `json:"available_benefits"`
	UpgradeProgress   *UpgradeProgress   `json:"upgrade_progress,omitempty"`
	SpecialRights     []SpecialRight     `json:"special_rights"`
}

// AppliedBenefit 已应用的权益
type AppliedBenefit struct {
	BenefitID   string  `json:"benefit_id"`
	Name        string  `json:"name"`
	Type        string  `json:"type"`
	Value       float64 `json:"value"`
	Discount    float64 `json:"discount"`
	Description string  `json:"description"`
}

// AvailableBenefit 可用权益
type AvailableBenefit struct {
	BenefitID   string  `json:"benefit_id"`
	Name        string  `json:"name"`
	Type        string  `json:"type"`
	Value       float64 `json:"value"`
	Description string  `json:"description"`
	ExpiryDate  int64   `json:"expiry_date"`
	UsageCount  int     `json:"usage_count"`
	Limit       int     `json:"limit"`
}

// UpgradeProgress 升级进度
type UpgradeProgress struct {
	CurrentLevel   int     `json:"current_level"`
	NextLevel      int     `json:"next_level"`
	CurrentPoints  int     `json:"current_points"`
	RequiredPoints int     `json:"required_points"`
	Progress       float64 `json:"progress"`
	Remaining      int     `json:"remaining"`
}

// NewMemberDiscountEngine 创建新的会员折扣引擎
func NewMemberDiscountEngine() *MemberDiscountEngine {
	return &MemberDiscountEngine{
		LevelRules: loadMemberLevelRules(),
	}
}

// CalculateMemberDiscount 计算会员折扣
func (mde *MemberDiscountEngine) CalculateMemberDiscount(req *MemberDiscountRequest) (*MemberDiscountResponse, error) {
	response := &MemberDiscountResponse{
		MemberLevel:     req.MemberLevel,
		OriginalPrice:   req.OriginalPrice,
		AppliedBenefits: []AppliedBenefit{},
	}

	// 获取会员等级规则
	levelRule, exists := mde.LevelRules[req.MemberLevel]
	if !exists {
		return response, errors.New("无效的会员等级")
	}

	response.LevelName = levelRule.Name
	response.DiscountRate = levelRule.DiscountRate

	// 计算基础折扣
	baseDiscount := req.OriginalPrice * (1 - levelRule.DiscountRate)
	response.DiscountAmount = baseDiscount

	// 应用会员权益
	appliedBenefits, additionalDiscount := mde.applyMemberBenefits(req, levelRule)
	response.AppliedBenefits = appliedBenefits
	response.DiscountAmount += additionalDiscount

	// 计算最终价格
	response.FinalPrice = math.Max(0, req.OriginalPrice-response.DiscountAmount)

	// 获取可用权益
	availableBenefits := mde.getAvailableBenefits(req, levelRule)
	response.AvailableBenefits = availableBenefits

	// 获取特殊权益
	specialRights := mde.getSpecialRights(req, levelRule)
	response.SpecialRights = specialRights

	// 计算升级进度
	upgradeProgress := mde.calculateUpgradeProgress(req)
	response.UpgradeProgress = upgradeProgress

	return response, nil
}

// applyMemberBenefits 应用会员权益
func (mde *MemberDiscountEngine) applyMemberBenefits(req *MemberDiscountRequest, levelRule *MemberLevelRule) ([]AppliedBenefit, float64) {
	var appliedBenefits []AppliedBenefit
	additionalDiscount := 0.0

	for _, benefit := range levelRule.Benefits {
		if mde.canApplyBenefit(benefit, req) {
			discount := mde.calculateBenefitDiscount(benefit, req)
			additionalDiscount += discount

			appliedBenefits = append(appliedBenefits, AppliedBenefit{
				BenefitID:   fmt.Sprintf("benefit_%s_%d", benefit.Type, levelRule.Level),
				Name:        benefit.Name,
				Type:        benefit.Type,
				Value:       benefit.Value,
				Discount:    discount,
				Description: benefit.Description,
			})
		}
	}

	return appliedBenefits, additionalDiscount
}

// canApplyBenefit 检查是否可以应用权益
func (mde *MemberDiscountEngine) canApplyBenefit(benefit MemberBenefit, req *MemberDiscountRequest) bool {
	// 检查有效期
	if benefit.ExpiryDate > 0 && benefit.ExpiryDate < time.Now().Unix() {
		return false
	}

	// 检查使用限制
	if benefit.Limit <= 0 {
		return false
	}

	// 检查使用频率
	if !mde.checkUsageFrequency(benefit, req) {
		return false
	}

	// 检查适用场景
	if !mde.checkApplicableScenario(benefit, req) {
		return false
	}

	return true
}

// checkUsageFrequency 检查使用频率
func (mde *MemberDiscountEngine) checkUsageFrequency(benefit MemberBenefit, req *MemberDiscountRequest) bool {
	// 这里可以查询数据库检查使用记录
	// 简化处理：假设已通过业务逻辑验证
	return true
}

// checkApplicableScenario 检查适用场景
func (mde *MemberDiscountEngine) checkApplicableScenario(benefit MemberBenefit, req *MemberDiscountRequest) bool {
	// 检查场地类型
	if benefit.Parameters != nil {
		params, ok := benefit.Parameters.(map[string]interface{})
		if ok {
			if venueTypes, exists := params["venue_types"].([]string); exists {
				found := false
				for _, vt := range venueTypes {
					if vt == req.VenueType {
						found = true
						break
					}
				}
				if !found {
					return false
				}
			}
		}
	}

	return true
}

// calculateBenefitDiscount 计算权益折扣
func (mde *MemberDiscountEngine) calculateBenefitDiscount(benefit MemberBenefit, req *MemberDiscountRequest) float64 {
	switch benefit.Type {
	case "percentage_discount":
		return req.OriginalPrice * (benefit.Value / 100)
	case "fixed_amount":
		return math.Min(benefit.Value, req.OriginalPrice)
	case "free_hours":
		// 免费时长权益
		pricePerHour := req.OriginalPrice / float64(req.Duration)
		return pricePerHour * benefit.Value
	case "birthday_discount":
		// 生日折扣权益
		if mde.isBirthday(req.MemberID, req.BookingDate) {
			return req.OriginalPrice * (benefit.Value / 100)
		}
	case "upgrade_bonus":
		// 升级奖励
		return benefit.Value
	default:
		return 0
	}

	return 0
}

// getAvailableBenefits 获取可用权益
func (mde *MemberDiscountEngine) getAvailableBenefits(req *MemberDiscountRequest, levelRule *MemberLevelRule) []AvailableBenefit {
	var availableBenefits []AvailableBenefit

	for _, benefit := range levelRule.Benefits {
		if mde.canApplyBenefit(benefit, req) {
			availableBenefits = append(availableBenefits, AvailableBenefit{
				BenefitID:   fmt.Sprintf("benefit_%s_%d", benefit.Type, levelRule.Level),
				Name:        benefit.Name,
				Type:        benefit.Type,
				Value:       benefit.Value,
				Description: benefit.Description,
				ExpiryDate:  benefit.ExpiryDate,
				Limit:       benefit.Limit,
			})
		}
	}

	return availableBenefits
}

// getSpecialRights 获取特殊权益
func (mde *MemberDiscountEngine) getSpecialRights(req *MemberDiscountRequest, levelRule *MemberLevelRule) []SpecialRight {
	return levelRule.SpecialRights
}

// calculateUpgradeProgress 计算升级进度
func (mde *MemberDiscountEngine) calculateUpgradeProgress(req *MemberDiscountRequest) *UpgradeProgress {
	_, exists := mde.LevelRules[req.MemberLevel]
	if !exists {
		return nil
	}

	// 获取下一等级规则
	nextLevel := req.MemberLevel + 1
	nextRule, exists := mde.LevelRules[nextLevel]
	if !exists {
		return nil
	}

	// 获取会员当前积分（这里需要查询数据库）
	currentPoints := mde.getMemberPoints(req.MemberID)

	progress := &UpgradeProgress{
		CurrentLevel:   req.MemberLevel,
		NextLevel:      nextLevel,
		CurrentPoints:  currentPoints,
		RequiredPoints: nextRule.UpgradeThreshold,
		Progress:       float64(currentPoints) / float64(nextRule.UpgradeThreshold) * 100,
		Remaining:      nextRule.UpgradeThreshold - currentPoints,
	}

	return progress
}

// getMemberPoints 获取会员积分
func (mde *MemberDiscountEngine) getMemberPoints(memberID int64) int {
	// 这里应该查询数据库获取会员积分
	// 简化处理：返回示例值
	return 850
}

// isBirthday 检查是否是生日
func (mde *MemberDiscountEngine) isBirthday(memberID int64, bookingDate string) bool {
	// 这里应该查询会员生日信息
	// 简化处理：返回示例值
	return false
}

// loadMemberLevelRules 加载会员等级规则
func loadMemberLevelRules() map[int]*MemberLevelRule {
	return map[int]*MemberLevelRule{
		1: {
			Level:        1,
			Name:         "普通会员",
			MinPoints:    0,
			MaxPoints:    999,
			DiscountRate: 1.0,
			Benefits: []MemberBenefit{
				{
					Type:        "welcome_bonus",
					Name:        "新用户欢迎礼",
					Description: "注册即送50积分",
					Value:       50,
					Limit:       1,
					Frequency:   "once",
				},
			},
			UpgradeThreshold: 1000,
			ValidityDays:     365,
			SpecialRights: []SpecialRight{
				{Type: "basic_support", Name: "基础客服支持", Description: "提供基础客服服务", Enabled: true},
			},
		},
		2: {
			Level:        2,
			Name:         "白银会员",
			MinPoints:    1000,
			MaxPoints:    4999,
			DiscountRate: 0.95,
			Benefits: []MemberBenefit{
				{
					Type:        "percentage_discount",
					Name:        "白银会员折扣",
					Description: "享受5%折扣",
					Value:       5,
					Limit:       9999,
					Frequency:   "per_booking",
				},
				{
					Type:        "free_hours",
					Name:        "免费时长",
					Description: "每月赠送30分钟免费时长",
					Value:       30,
					Limit:       1,
					Frequency:   "monthly",
				},
			},
			UpgradeThreshold: 5000,
			ValidityDays:     365,
			SpecialRights: []SpecialRight{
				{Type: "priority_booking", Name: "优先预约权", Description: "热门时段优先预约", Enabled: true},
				{Type: "birthday_discount", Name: "生日折扣", Description: "生日当月享受额外折扣", Enabled: true},
			},
		},
		3: {
			Level:        3,
			Name:         "黄金会员",
			MinPoints:    5000,
			MaxPoints:    19999,
			DiscountRate: 0.90,
			Benefits: []MemberBenefit{
				{
					Type:        "percentage_discount",
					Name:        "黄金会员折扣",
					Description: "享受10%折扣",
					Value:       10,
					Limit:       9999,
					Frequency:   "per_booking",
				},
				{
					Type:        "free_hours",
					Name:        "免费时长",
					Description: "每月赠送60分钟免费时长",
					Value:       60,
					Limit:       1,
					Frequency:   "monthly",
				},
				{
					Type:        "upgrade_bonus",
					Name:        "升级奖励",
					Description: "升级时赠送100积分",
					Value:       100,
					Limit:       1,
					Frequency:   "once",
				},
			},
			UpgradeThreshold: 20000,
			ValidityDays:     365,
			SpecialRights: []SpecialRight{
				{Type: "priority_booking", Name: "优先预约权", Description: "热门时段优先预约", Enabled: true},
				{Type: "exclusive_venues", Name: "专属场地", Description: "可预约专属会员场地", Enabled: true},
				{Type: "vip_support", Name: "VIP客服", Description: "专属VIP客服通道", Enabled: true},
			},
		},
		4: {
			Level:        4,
			Name:         "钻石会员",
			MinPoints:    20000,
			MaxPoints:    999999,
			DiscountRate: 0.85,
			Benefits: []MemberBenefit{
				{
					Type:        "percentage_discount",
					Name:        "钻石会员折扣",
					Description: "享受15%折扣",
					Value:       15,
					Limit:       9999,
					Frequency:   "per_booking",
				},
				{
					Type:        "free_hours",
					Name:        "免费时长",
					Description: "每月赠送120分钟免费时长",
					Value:       120,
					Limit:       1,
					Frequency:   "monthly",
				},
				{
					Type:        "upgrade_bonus",
					Name:        "升级奖励",
					Description: "升级时赠送500积分",
					Value:       500,
					Limit:       1,
					Frequency:   "once",
				},
				{
					Type:        "birthday_discount",
					Name:        "生日折扣",
					Description: "生日当月享受额外20%折扣",
					Value:       20,
					Limit:       1,
					Frequency:   "yearly",
				},
			},
			ValidityDays: 365,
			SpecialRights: []SpecialRight{
				{Type: "priority_booking", Name: "优先预约权", Description: "热门时段优先预约", Enabled: true},
				{Type: "exclusive_venues", Name: "专属场地", Description: "可预约专属会员场地", Enabled: true},
				{Type: "vip_support", Name: "VIP客服", Description: "专属VIP客服通道", Enabled: true},
				{Type: "free_cancellation", Name: "免费取消", Description: "24小时内免费取消", Enabled: true},
				{Type: "exclusive_events", Name: "专属活动", Description: "参与会员专属活动", Enabled: true},
			},
		},
	}
}

// GetMemberLevelByPoints 根据积分获取会员等级
func GetMemberLevelByPoints(points int) int {
	rules := loadMemberLevelRules()

	for level, rule := range rules {
		if points >= rule.MinPoints && points < rule.MaxPoints {
			return level
		}
	}

	return 1 // 默认普通会员
}

// CalculateUpgradePoints 计算升级所需积分
func CalculateUpgradePoints(currentLevel int, targetLevel int) int {
	rules := loadMemberLevelRules()

	if targetRule, exists := rules[targetLevel]; exists {
		return targetRule.UpgradeThreshold
	}

	return 0
}

// GetMemberBenefitsByLevel 获取会员等级权益
func GetMemberBenefitsByLevel(level int) []MemberBenefit {
	rules := loadMemberLevelRules()

	if rule, exists := rules[level]; exists {
		return rule.Benefits
	}

	return []MemberBenefit{}
}

// ValidateMemberDiscount 验证会员折扣
func (mde *MemberDiscountEngine) ValidateMemberDiscount(req *MemberDiscountRequest) error {
	if req.MemberID <= 0 {
		return errors.New("会员ID无效")
	}

	if req.MemberLevel < 1 || req.MemberLevel > 4 {
		return errors.New("会员等级无效")
	}

	if req.OriginalPrice <= 0 {
		return errors.New("原价必须大于0")
	}

	return nil
}

// UpdateMemberPoints 更新会员积分
func (mde *MemberDiscountEngine) UpdateMemberPoints(memberID int64, points int, operation string) error {
	// 这里应该更新数据库中的会员积分
	// 简化处理：返回成功
	return nil
}

// CheckMemberLevelUpgrade 检查会员等级升级
func (mde *MemberDiscountEngine) CheckMemberLevelUpgrade(memberID int64, currentPoints int) (bool, int) {
	currentLevel := GetMemberLevelByPoints(currentPoints)
	nextLevel := currentLevel + 1

	requiredPoints := CalculateUpgradePoints(currentLevel, nextLevel)
	if currentPoints >= requiredPoints {
		return true, nextLevel
	}

	return false, currentLevel
}

// GenerateMemberReport 生成会员报告
func (mde *MemberDiscountEngine) GenerateMemberReport(memberID int64) (*MemberReport, error) {
	// 这里应该查询数据库获取会员详细信息
	// 简化处理：返回示例报告
	return &MemberReport{
		MemberID:          memberID,
		Level:             3,
		Points:            8500,
		TotalSavings:      1250.50,
		BenefitsUsed:      12,
		RemainingBenefits: 5,
	}, nil
}

// MemberReport 会员报告
type MemberReport struct {
	MemberID          int64   `json:"member_id"`
	Level             int     `json:"level"`
	Points            int     `json:"points"`
	TotalSavings      float64 `json:"total_savings"`
	BenefitsUsed      int     `json:"benefits_used"`
	RemainingBenefits int     `json:"remaining_benefits"`
}

// GetMemberDiscountForBooking 为预约获取会员折扣
func GetMemberDiscountForBooking(memberID int64, memberLevel int, originalPrice float64) (*MemberDiscountResponse, error) {
	engine := NewMemberDiscountEngine()

	req := &MemberDiscountRequest{
		MemberID:      memberID,
		MemberLevel:   memberLevel,
		OriginalPrice: originalPrice,
		BookingType:   "normal",
		BookingDate:   time.Now().Format("2006-01-02"),
	}

	return engine.CalculateMemberDiscount(req)
}
